home *** CD-ROM | disk | FTP | other *** search
- /*
- * SMARTMEM.C
- *
- * (c)Copyright 1991-93 by Tobias Ferber, All Rights Reserved.
- */
-
- #include <stdlib.h>
-
- #include <exec/types.h>
- #include <exec/memory.h>
-
- /* exec.library prototypes */
- extern void *AllocMem(ULONG,ULONG);
- extern void FreeMem(void *,ULONG);
-
- #include "newlook.h"
-
- /*
- * --- PRIVATE ---
- */
-
- /****i* newlook.lib/--background-- ******************************************
- *
- * SMARTMEM
- * smartmem.o offers some very useful functions concering
- * memory management on Amiga systems.
- * ... bla, bla, bla ...
- *
- * IDEAS
- * SmartAllocRaster()
- * SmartAllocMem(<bytesize>,<memory-type>)
- *
- * typedef struct memnode {
- *
- * struct memnode *succ,*pred;
- * ULONG handle;
- *
- * union {
- * APTR memory;
- * PLANEPTR plane;
- * } ptr;
- *
- * union {
- * ULONG bytesize;
- * struct {
- * USHORT width,
- * height;
- * } dimen;
- * } size;
- *
- * enum { RASTER,MEMORY } type; /* memtype attributes */
- * } memnode_t;
- *
- ******************************************************************************
- *
- */
-
- typedef struct memnode {
-
- struct memnode *succ,
- *pred;
- ULONG handle;
- void *memory;
- ULONG bytesize;
-
- } memnode_t;
-
- #define NIL(type) (type)0L
- static memnode_t *memlist= NIL(memnode_t *);
- static ULONG current_handle= 0L;
-
- /****i* newlook.lib/tail ******************************************
- *
- * NAME
- * tail -- Return the last memnode pointer in a list
- *
- * SYNOPSIS
- * t = tail( n )
- *
- * memnode_t *tail( memnode_t * );
- *
- * FUNCTION
- * Traverse the list of memnodes linked to n->succ until
- * n->succ is == NIL(menode_t *).
- *
- * INPUTS
- * n - pointer to any memnode or NIL(memnode_t *)
- *
- * RESULT
- * t - the last memnode or NIL(memnode_t *) if n was NIL(memnode_t *)
- *
- * SEE ALSO
- * head()
- *
- ******************************************************************************
- *
- */
-
- static memnode_t *tail(memnode_t *n)
- {
- return (n && n->succ) ? tail(n->succ) : n;
- }
-
-
- /****i* newlook.lib/head ******************************************
- *
- * NAME
- * head -- Return the first memnode pointer in a list
- *
- * SYNOPSIS
- * t = head( n )
- *
- * memnode_t *head( memnode_t * );
- *
- * FUNCTION
- * Traverse the list of memnodes linked to n->pred until
- * n->pred is == NIL(menode_t *).
- *
- * INPUTS
- * n - pointer to any memnode or NIL(memnode_t *)
- *
- * RESULT
- * t - the last memnode or NIL(memnode_t *) if n was NIL(memnode_t *)
- *
- * SEE ALSO
- * tail()
- *
- ******************************************************************************
- *
- */
-
- static memnode_t *head(memnode_t *n)
- {
- return (n && n->pred) ? head(n->pred) : n;
- }
-
-
- /****i* newlook.lib/addnode ******************************************
- *
- * NAME
- * addnode -- Add a (list of) memnode(s) to the head of memlist
- *
- * SYNOPSIS
- * addnode( n )
- *
- * void addnode( memnode_t * );
- *
- * FUNCTION
- * Add memlist to the tail of n and make n the head of the new memlist
- *
- * INPUTS
- * n - pointer to any memnode or NIL(memnode_t *)
- *
- * RESULT
- * None.
- *
- * NOTES
- * calling addnode( NIL(memnode_t *) ) is a no-op.
- *
- * SEE ALSO
- * new()
- *
- ******************************************************************************
- *
- */
-
- static void addnode(memnode_t *n)
- {
- register memnode_t *t;
-
- if(t= tail(n))
- {
- if( t->succ= head(memlist) )
- t->succ->pred= t;
-
- memlist= head(n);
- }
- }
-
-
- /****i* newlook.lib/new ******************************************
- *
- * NAME
- * new -- Allocate and initialize a new memnode
- *
- * SYNOPSIS
- * n= new()
- *
- * memnode_t *new( void );
- *
- * FUNCTION
- * Allocate a new memnode using malloc() and initialize it.
- * Especially the current handle will be copied to n->handle.
- *
- * INPUTS
- * None.
- *
- * RESULT
- * n - pointer to the new memnode or NIL(memnode_t *) on error.
- *
- * NOTES
- * calling new() will not automatically chain the the new memnode
- *
- * SEE ALSO
- * addnode()
- *
- ******************************************************************************
- *
- */
-
- static memnode_t *new(void)
- {
- register memnode_t *n;
-
- if(n= (memnode_t *)malloc(sizeof(memnode_t)))
- {
- n->succ=
- n->pred= NIL(memnode_t *);
-
- n->handle= current_handle;
-
- n->memory= NIL(void *);
- n->bytesize= 0UL;
- }
- return n;
- }
-
-
- /****i* newlook.lib/dispose ******************************************
- *
- * NAME
- * dispose -- Unchain a memnode from memlist and free it
- *
- * SYNOPSIS
- * dispose( n );
- *
- * void dispose( memnode_t * );
- *
- * FUNCTION
- * Unchain n and keep memlist sane.
- *
- * INPUTS
- * n - pointer to the memnode which is about to be disposed
- *
- * RESULT
- * None.
- *
- * NOTES
- * n->memory is _NOT_ freed by this function!
- * If n is the last node in memlist then memlist is set to NIL.
- *
- * SEE ALSO
- * new(), addnode()
- *
- ******************************************************************************
- *
- */
-
- static void dispose(memnode_t *n)
- {
- if(n->pred == n->succ)
- { /* hacky: they _must_ be both NIL to be equal... */
- memlist= NIL(memnode_t *);
- }
- else
- {
- if(n == memlist)
- {
- if(n->pred)
- memlist= head(n->pred); /* should not happen */
- else
- memlist= n->succ;
- }
-
- if(n->pred)
- n->pred->succ= n->succ;
-
- if(n->succ)
- n->succ->pred= n->pred;
-
- n->pred=
- n->succ= NIL(memnode_t *);
- }
- free(n);
- }
-
-
- /****i* newlook.lib/findnode ******************************************
- *
- * NAME
- * findnode -- Find a memnode with memory at a certain location
- *
- * SYNOPSIS
- * n = findnode( mem );
- *
- * memnode_t *findnode( void * );
- *
- * FUNCTION
- * Scan memlist for a memnode which has memory allocated at given
- * location "mem" with the current memory management handle.
- *
- * INPUTS
- * mem - pointer to the memory returned by SmartAllocMem()
- * or the macro SmartAllocate()
- *
- * RESULT
- * n - the memnode with n->memory equal to mem and n->handle
- * equal to the current_handle.
- *
- * SEE ALSO
- * addnode()
- *
- ******************************************************************************
- *
- */
-
- static memnode_t *findnode(void *mem)
- {
- register memnode_t *n= head(memlist);
-
- /*for(n= head(memlist); n && n->memory != mem; n= n->succ) ;*/
-
- while(n && n->memory != mem)
- n= n->succ;
-
- return (n && n->handle == current_handle) ? n : NIL(memnode_t *);
- }
-
-
- /*
- * --- PUBLIC ---
- */
-
- /****** newlook.lib/SetNewLookHandle ******************************************
- *
- * NAME
- * SetNewLookHandle -- Set the current memory management handle
- *
- * SYNOPSIS
- * lastHandle = SetNewLookHandle( newHandle )
- *
- * ULONG SetNewLookHandle( ULONG );
- *
- * FUNCTION
- * Set the current memory management handle to newHandle and return
- * the last handle.
- *
- * INPUTS
- * newHandle - a unique number > 0 to identify your memory.
- *
- * RESULT
- * lastHandle - the last handle.
- *
- * NOTES
- * There are some reserved handles such as PRIVATE_HANDLE or
- * MAGIC_HANDLE which you must not use here!
- *
- * SEE ALSO
- * MakePrivateHandlePublic()
- *
- ******************************************************************************
- *
- */
-
- ULONG SetNewLookHandle(ULONG new_handle)
- {
- register ULONG last_handle= current_handle;
- current_handle= new_handle;
- return last_handle;
- }
-
-
- /****** newlook.lib/SmartAllocMem ******************************************
- *
- * NAME
- * SmartAllocMem -- Allocate and remember memory for a handle
- *
- * SYNOPSIS
- * mem = SmartAllocMem( numbytes, attributes )
- *
- * void *SmartAllocMem( ULONG, ULONG );
- *
- * FUNCTION
- * Allocate system memory via AllocMem() and chain it to the
- * newlook memlist using the current memory management handle.
- *
- * INPUTS
- * numbytes - The size of the desired block in bytes. (The
- * operating system will automatically round this
- * number to a multiple of the system memory chunk
- * size.)
- * attributes - requirements as explained in exec.library autodoc
- * file and/or exec/memory.h
- *
- * RESULT
- * mem - a pointer to the newly allocated memory block.
- * If there are no free memory regions large enough to satisfy
- * the request, zero will be returned. The pointer must be
- * checked for zero before the memory block may be used!
- * The memory block returned is long word aligned.
- *
- * SEE ALSO
- * SetNewLookHandle(), SmartAllocate(), SmartFree(), SmartFreeAll()
- * exec.library/AllocMem()
- *
- ******************************************************************************
- *
- */
-
- void *SmartAllocMem(ULONG numbytes, ULONG attributes)
- {
- register memnode_t *n;
- register void *mem= NIL(void *);
-
- if(n= new())
- {
- if(mem= (void *)AllocMem(numbytes, attributes))
- {
- n->memory= mem;
- n->bytesize= numbytes;
- addnode(n);
- }
- else dispose(n);
- }
- return mem;
- }
-
-
- #ifdef OBSOLETE
-
- /****** newlook.lib/SmartRemember ******************************************
- *
- * NAME
- * SmartRemember -- Remember manually allocated memory (obsolete)
- *
- * SYNOPSIS
- * success = SmartRemember( mem, numbytes )
- *
- * int SmartRemember( void *, ULONG );
- *
- * FUNCTION
- * Chain given memory block "mem" to the newlook memlist using
- * the current memory management handle.
- *
- * INPUTS
- * mem - pointer to a memory block which has been
- * allocated via AllocMem()
- * numbytes - the size of the allocated memory block in
- * bytes.
- *
- * RESULT
- * success - 1 on success, 0 on error
- *
- * NOTES
- * This function is declared obsolete and will be removed!
- *
- * SEE ALSO
- * SmartAllocMem(), exec.library/AllocMem()
- *
- ******************************************************************************
- *
- */
-
- int SmartRemember(void *mem, ULONG numbytes)
- {
- register memnode_t *n= NIL(memnode_t *);
-
- if(mem && numbytes)
- {
- if(n= new())
- {
- n->memory= mem;
- n->bytesize= numbytes;
- addnode(n);
- }
- }
- return n ? 1:0;
- }
- #endif /* OBSOLETE */
-
-
- /****** newlook.lib/SmartFree ******************************************
- *
- * NAME
- * SmartFree -- Free memory allocated via SmartAllocMem()
- *
- * SYNOPSIS
- * nil = SmartFree( mem )
- *
- * void *SmartFree( void * );
- *
- * FUNCTION
- * Free the memory block allocated via SmartAllocMem() and
- * the current memory management handle.
- *
- * INPUTS
- * mem - pointer to the memory block returned by SmartAllocMem()
- *
- * RESULT
- * nil - a constant pointer to NIL(void *)
- *
- * NOTES
- * If given pointer "mem" has never been returned by SmartAllocMem()
- * or if it has already been freed up then calling this function is
- * a no-op.
- *
- * SEE ALSO
- * SmartAllocMem(), SmartFreeAll()
- *
- ******************************************************************************
- *
- */
-
- void *SmartFree(void *mem)
- {
- register memnode_t *n;
-
- if( n= findnode(mem) )
- {
- if(n->memory && n->bytesize)
- FreeMem(mem,n->bytesize);
-
- dispose(n);
- }
- return NIL(void *);
- }
-
-
- /****** newlook.lib/SmartFreeAll ******************************************
- *
- * NAME
- * SmartFreeAll -- Free all memory allocated for a certain handle
- *
- * SYNOPSIS
- * nil = SmartFreeAll( handle )
- *
- * void *SmartFreeAll( ULONG );
- *
- * FUNCTION
- * Free all the memory which has been allocated via SmartAllocMem()
- * for the given newlook handle.
- *
- * INPUTS
- * handle - the handle to be freed or MAGIC_HANDLE for all handles
- *
- * RESULT
- * nil - a constant pointer to NIL(void *)
- *
- * NOTES
- * Calling SmartFreeAll( MAGIC_HANDLE ) will free all memory ever
- * chained to the memlist.
- *
- * SEE ALSO
- * SmartFree(), SmartAllocMem()
- *
- ******************************************************************************
- *
- */
-
- void *SmartFreeAll(ULONG handle)
- {
- register memnode_t *n= head(memlist);
-
- while(n)
- {
- register memnode_t *t= n;
- n= n->succ;
-
- if(t->handle == handle || handle == MAGIC_HANDLE)
- {
- if(t->memory && t->bytesize)
- FreeMem(t->memory, t->bytesize);
-
- dispose(t);
- }
- }
- return NIL(void *);
- }
-
-
- #ifdef DEBUG
-
- /****** newlook.lib/DebugSmartMemList ******************************************
- *
- * NAME
- * DebugSmartMemList -- Print all memnodes in memlist
- *
- * SYNOPSIS
- * DebugSmartMemList()
- *
- * void DebugSmartMemList( void );
- *
- * FUNCTION
- * Traverse the memlist and print information about all nodes chained
- * to it.
- *
- * NOTES
- * This function is only available when comiled w/ -DDEBUG !
- *
- ******************************************************************************
- *
- */
-
- void DebugSmartMemList(void)
- {
- register memnode_t *n= head(memlist);
-
- if(n)
- {
- printf(" Handle | Memory | Bytesize\n"
- "----------+----------+------------\n");
-
- while(n)
- {
- printf("%9ld | 0x%06lX | %ld\n",n->handle,n->memory,n->bytesize);
- n= n->succ;
- }
- }
- else printf("%s: Memory list is empty.\n",__FILE__);
- }
- #endif /* DEBUG */
-
-
- /*
- * --- NewLook PRIVATE ---
- */
-
- /****** newlook.lib/MakePrivateHandlePublic ******************************************
- *
- * NAME
- * MakePrivateHandlePublic -- change memory handle from private to public
- *
- * SYNOPSIS
- * MakePrivateHandlePublic( publicHandle )
- *
- * void MakePrivateHandlePublic( ULONG );
- *
- * FUNCTION
- * Traverse the memlist and change all memnodes with a memory block
- * allocated with the PRIVATE_HANDLE to the given publicHandle.
- *
- * INPUTS
- * publicHandle - The new handle for the private memnodes.
- *
- * RESULT
- * None.
- *
- * EXAMPLE
- * Federal regulations prohibit a demonstration of this function.
- *
- * NOTES
- * This function is newlook private and should not be called by the
- * user!
- *
- * SEE ALSO
- * SetNewLookHandle(), SmartAllocMem()
- *
- ******************************************************************************
- *
- */
-
- void MakePrivateHandlePublic(ULONG public_handle)
- {
- if(public_handle != PRIVATE_HANDLE)
- {
- register memnode_t *n= head(memlist);
-
- while(n)
- {
- if(n->handle == PRIVATE_HANDLE)
- n->handle= public_handle;
-
- n= n->succ;
- }
- }
- current_handle= public_handle;
- }
-